package com.zhanglu.authentication.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Getter;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description token工具类
 * @Auther zhanglu
 * @Date 2017/10/13 下午4:56
 */
@Component
@Getter
@Slf4j
public class TokenUtil {
    @val
    private String SECRET      = "zhanglu-auth-info";  // key暂时不加密，由字符串代替
    @val
    private String COOKIE_AUTH = "zhanglu-auth-token"; // cookie存放token的名称

    public String createJWT(AuthenticationUser user, List<String> roles) {
        return Jwts.builder()
            .setSubject(user.getUsername())
            .setIssuer("ZhangLu")
            .setExpiration(user.getExpireDate())
            .claim("email", user.getEmail())
            .claim("nickName", user.getNickName())
            .claim("roles", roles.stream().collect(Collectors.joining(",")))
            .signWith(SignatureAlgorithm.HS256, SECRET)
            .compact();
    }

    public AuthenticationUser parserToken(String token) {
        Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList(claims.get("roles", String.class));
        return new AuthenticationUser(
                claims.getSubject(),
                claims.get("nickName", String.class),
                claims.get("email", String.class),
                claims.getExpiration(),
                auths
        );
    }

    public void setCookie(HttpServletResponse httpServletResponse, @NonNull String token) {
        Cookie cookie = new Cookie(COOKIE_AUTH, token);
        cookie.setPath("/");
        cookie.setMaxAge(60 * 60 * 12 * 14);
        httpServletResponse.addCookie(cookie);
    }

    public void setRequestCookie(HttpServletRequest request, @NonNull String token) {
        Arrays.stream(request.getCookies()).forEach(cookie -> { // 这里把request里面设置一下
            if (COOKIE_AUTH.equalsIgnoreCase(cookie.getName())) {
                cookie.setValue(token);
                cookie.setPath("/");
                cookie.setMaxAge(60 * 60 * 12 * 14);
            }
        });
    }

    public void removeResponseAuthCookie(HttpServletResponse httpServletResponse) {
        // remove the auth cookie if they have it.
        Cookie cookie = new Cookie(COOKIE_AUTH, null);
        cookie.setPath("/");
        cookie.setMaxAge(0);
        httpServletResponse.addCookie(cookie);
    }

    public void removeRequestAuthCookie(HttpServletRequest request) {
        Arrays.stream(request.getCookies()).forEach(cookie -> { // 这里把request里面设置null
            if (COOKIE_AUTH.equalsIgnoreCase(cookie.getName())) {
                cookie.setValue(null);
                cookie.setMaxAge(0);
            }
        });
    }
}
